Skip to content

feat(telemetry): add export command#953

Open
EhabY wants to merge 9 commits into
feat/issue-903-export-telemetry-otlp-writerfrom
feat/issue-903-export-telemetry
Open

feat(telemetry): add export command#953
EhabY wants to merge 9 commits into
feat/issue-903-export-telemetry-otlp-writerfrom
feat/issue-903-export-telemetry

Conversation

@EhabY
Copy link
Copy Markdown
Collaborator

@EhabY EhabY commented May 13, 2026

Summary

  • add the coder.exportTelemetry command UI flow
  • register the command through CommandManager and package contributions
  • connect date-range selection, format selection, save dialog, export progress, and telemetry flushing

Closes #903.
Follow-up: #952 tracks adding recent local telemetry to support bundles.

Stack: 4 / 4. Base: #961.

Review follow-up

  • adds TelemetryService.flush()
  • flushes buffered local telemetry before discovering and reading telemetry files so recent events are included

Validation

  • pnpm test:extension ./test/unit/telemetry/export/range.test.ts ./test/unit/telemetry/export/files.test.ts ./test/unit/telemetry/export/writers.test.ts ./test/unit/core/commandManager.test.ts
  • pnpm test:extension
  • pnpm typecheck
  • pnpm lint
  • pnpm format:check
  • pnpm build

Generated by Coder Agents.

@EhabY EhabY self-assigned this May 13, 2026
@EhabY EhabY force-pushed the feat/issue-903-export-telemetry branch from 35eba99 to 821a950 Compare May 13, 2026 14:37
@EhabY EhabY force-pushed the feat/issue-906-auth-workspace-telemetry branch 5 times, most recently from 18ab98f to 5523f85 Compare May 15, 2026 10:01
@EhabY EhabY force-pushed the feat/issue-903-export-telemetry branch from 821a950 to 728e014 Compare May 15, 2026 10:06
@EhabY EhabY changed the base branch from feat/issue-906-auth-workspace-telemetry to main May 15, 2026 10:06
@EhabY EhabY force-pushed the feat/issue-903-export-telemetry branch from 728e014 to c450036 Compare May 17, 2026 17:09
@EhabY EhabY changed the title feat(telemetry): export local telemetry feat(telemetry): add export command May 17, 2026
@EhabY EhabY changed the base branch from main to feat/issue-903-export-telemetry-otlp-writer May 17, 2026 17:10
@EhabY EhabY force-pushed the feat/issue-903-export-telemetry branch from c450036 to 4daf2f8 Compare May 17, 2026 19:42
@EhabY EhabY force-pushed the feat/issue-903-export-telemetry-otlp-writer branch from ab7dcf4 to acadd7e Compare May 17, 2026 19:42
@EhabY EhabY force-pushed the feat/issue-903-export-telemetry branch from 4daf2f8 to 9534418 Compare May 18, 2026 17:03
@EhabY EhabY force-pushed the feat/issue-903-export-telemetry-otlp-writer branch 5 times, most recently from 539131f to fe6675e Compare May 20, 2026 10:29
@EhabY EhabY force-pushed the feat/issue-903-export-telemetry branch 2 times, most recently from 25db18c to d70fc4b Compare May 20, 2026 10:45
@EhabY EhabY force-pushed the feat/issue-903-export-telemetry-otlp-writer branch 2 times, most recently from 55cccf2 to 71bcce7 Compare May 21, 2026 09:55
@EhabY EhabY force-pushed the feat/issue-903-export-telemetry branch 2 times, most recently from e762a74 to 1a94594 Compare May 21, 2026 10:33
@EhabY EhabY force-pushed the feat/issue-903-export-telemetry-otlp-writer branch from 7ce5f22 to d9f955a Compare May 21, 2026 15:14
@EhabY EhabY force-pushed the feat/issue-903-export-telemetry branch from 1a94594 to 5439875 Compare May 21, 2026 15:15
EhabY added 5 commits May 21, 2026 18:53
Move `tempFilePath` and `renameWithRetry` from `src/util.ts` into a
focused `src/util/fs.ts`, alongside a new `writeAtomically(path, write)`
helper that captures the temp-file + rename + best-effort cleanup
pattern previously copy-pasted into the telemetry writer and
`CliCredentialManager.atomicWriteFile`. Both call sites now use the
shared helper; the SSH config / support bundle / CLI manager keep their
bespoke flows and just update imports.

Rewrite `writeJsonArrayExport` to stream chunks through
`Readable.from(...)` into `createWriteStream` via `stream/promises`
`pipeline`. Memory stays flat regardless of `maxTotalBytes`, which has
no enforced ceiling and can comfortably exceed the default 100 MB cap.

Tests for `tempFilePath` and `renameWithRetry` move into
`test/unit/util/fs.test.ts` alongside a new `writeAtomically` suite
covering success, partial-write rollback, and callback return values.
- Move src/telemetry/export/writers.ts to writers/json.ts and the
  matching test to writers/json.test.ts. The writer keeps the same
  shape; the doc comment is tightened and the test drops a
  redundant atomic-failure assertion already covered by
  writeAtomically's own tests.
- Extract parseTelemetryTimestampMs from range.ts's
  isTimestampInRange so other export writers can reuse it.
- Add a trivial asyncIterable test helper to test/mocks/.
- Inline the duplicated `vi.mock("node:fs", ...)` /
  `vi.mock("node:fs/promises", ...)` factory pair (9 lines per file)
  as a 2-line dynamic import in the affected test files.

Upstream-compatible groundwork for the OTLP writer branch (#961);
isolates move + helper-extraction churn so that PR's diff stays
focused on OTLP-specific work.
- Add a required onCleanupError callback to writeAtomically and
  writeJsonArrayExport so callers cannot silently lose temp-file
  cleanup diagnostics (matters on Windows, where AV/Indexer locks
  can leave large export orphans). cliCredentialManager passes its
  logger to restore the warn-on-cleanup behavior that existed
  before the extraction.
- Wrap the rm+callback chain in a try/catch so a throwing
  onCleanupError can't replace the original write error.
- Document that writeAtomically requires the parent directory to
  exist.
- Use suffix "temp" so the call matches the doc example and the
  cliManager convention.
- Cover the cleanup-failure path with new tests: callback invoked
  with the rm error, and a throwing callback still surfaces the
  writer's error.
- Tighten the json writer's midstream-error test to assert the
  destination survives and no temp file is left behind.
- Fix the asyncIterable helper's docstring: it exercises async
  iteration, not stream backpressure.
After the 999->888 takeover, the 888 monitor would eventually fail
network reads, call processLost, then searchForProcess would find
888 again and emit ssh.process.recovered (same-PID rediscovery).
On slow CI runners that race won the negative assertion at
sshProcess.test.ts:469. Return [] from find after the takeover so
no rediscovery is possible.
@EhabY EhabY force-pushed the feat/issue-903-export-telemetry-otlp-writer branch from d9f955a to f7308bf Compare May 21, 2026 16:00
@EhabY EhabY force-pushed the feat/issue-903-export-telemetry branch 2 times, most recently from 541629e to e31dd3e Compare May 21, 2026 16:10
EhabY added 2 commits May 21, 2026 19:14
- Restructure: writers.ts → writers/json.ts; combine OTLP mapping and
  writer into writers/otlp.ts; lift signal classification into
  export/signal.ts.
- Group all records of each signal under a single Resource block per
  file (was one Resource per event), matching the OTLP spec's
  recommended shape and shrinking exports at scale.
- Adopt OTLP enums from @opentelemetry/api + api-logs; document the
  +1 wire offset on SpanKind.
- Tighten the public surface: only writeOtlpZipExport and
  OtlpExportCounts are exported; record mappers are module-private.
- Hoist per-event metric attributes once; single-pass partition of
  http.requests measurements into counts and gauges.
- Share parseTelemetryTimestampMs between range.ts and the OTLP
  writer's nanos conversion (was duplicated with identical error).
- Extract asyncIterable test helper to test/mocks/; inline the memfs
  vi.mock pair across affected test files.
- Tests now exercise the public API only, dropping side-effect
  assertions about staging cleanup and atomic semantics already
  covered by writeAtomically's own tests.
Wire-format fixes:
- Switch http.requests count_* sums from DELTA to CUMULATIVE temporality
  (Prom/Mimir/Grafana Cloud reject the delta+sum combination).
- Maintain per-series running totals across the export, anchored at the
  first observed window's startTimeUnixNano.
- Suppress zero-cumulative counters so routes that never errored don't
  ship empty data points.

Semantic-convention compliance:
- Use OTel-standard `service.instance.id` (was `coder.session.id`) and
  `host.id` (was `coder.machine.id`) for portability with OTel-aware
  backends. The previous vendor keys were pure aliases.
- Add `schemaUrl` to each ResourceLogs/ResourceSpans/ResourceMetrics
  container and each scope container.
- Stamp scope.version with the extension version.
@EhabY EhabY force-pushed the feat/issue-903-export-telemetry-otlp-writer branch from f7308bf to 6ac4715 Compare May 21, 2026 16:14
@EhabY EhabY force-pushed the feat/issue-903-export-telemetry branch from e31dd3e to 87b5f8d Compare May 21, 2026 16:15
@EhabY EhabY force-pushed the feat/issue-903-export-telemetry-otlp-writer branch 2 times, most recently from 3187fae to 4574a38 Compare May 26, 2026 14:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Telemetry: coder.exportTelemetry command (Logs, Traces, and Metrics OTLP/JSON)

1 participant